package com.lions.client.view.mappanel;

import com.allen_sauer.gwt.dnd.client.DragContext;
import com.allen_sauer.gwt.dnd.client.DragEndEvent;
import com.allen_sauer.gwt.dnd.client.DragHandler;
import com.allen_sauer.gwt.dnd.client.DragStartEvent;
import com.allen_sauer.gwt.dnd.client.PickupDragController;
import com.allen_sauer.gwt.dnd.client.VetoDragException;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.lions.client.model.HTMLStorage;
import com.lions.client.model.Model;
import com.lions.client.model.Module;
import com.lions.client.model.ModuleList;
import com.lions.client.view.modulepanel.ModulePanel;
import com.lions.client.view.popup.MyPopupPanel;

/**
 * Builds the draggable panel.
 * @author Brad
 */
public class SandboxMapPanel extends ScrollPanel {

	/**
	 * Constructor to build the draggable panel.
	 * @param m Model
	 */
	public SandboxMapPanel(final Model m) {
		super();
		height = 50;
		width = 100;
		map = new Grid(height, width);
		map.setStyleName("gwt-Grid");
		map.setCellPadding(0);
		map.setCellSpacing(0);
		model = m;
		populateAndCopy();
		this.add(map);

		// Setting up the buttons.
		resetButton = new Button("Update and Revert");
		resetButton.setStyleName(buttonStyle);
		//commitButton = new Button("Commit Changes");
		//commitButton.setStyleName(buttonStyle);
		buttonPanel = new HorizontalPanel();
		buttonPanel.setHorizontalAlignment(HasAlignment.ALIGN_CENTER);
		buttonPanel.add(resetButton);
		//buttonPanel.add(commitButton);
		buildButtonListeners();
		
		// Sets the ScrollPanels widget.
		absolutePanel = new AbsolutePanel();
		absolutePanel.setSize("100%", "100%");		
		absolutePanel.add(this.map);
		
		// Setup Panel wrapper.
		vertPanel = new VerticalPanel();
		vertPanel.add(buttonPanel);
		vertPanel.add(absolutePanel);
		setWidget(vertPanel);

		dragController = new PickupDragController(absolutePanel, true);
		dragController.setBehaviorMultipleSelection(false);
		buildDragController();
	}
	
	public void addModulePanel(ModulePanel modP) {
		this.modulePanel = modP;
	}

	/**
	 * Redraws all of the map panels images.
	 */
	public void populate() {
		int yInverter = 0;
		map.clear();
		for (int i = 0; i < 10; i++) {
			for (int j = 40; j < 50; j++) {
				map.setWidget(i, j, new Image("images/UNUSABLE.jpg"));
			}
		}
		ModuleList moduleList = model.getModuleList();
		Module[][] container = new Module[height][width];
		for (Module module : moduleList) {
			if ((module.getX() < 100) && (module.getY() < 50))
				container[module.getY()][module.getX()] = module;
		}
		for (int row = 49; row >= 0; row--) {
			for (int col = 99; col >= 0; col--) {
				SimplePanel simplePanel = new SimplePanel();
				simplePanel.setPixelSize(15, 15);
				map.setWidget(yInverter, col, simplePanel);
				if (container[row][col] != null) {
					simplePanel.setWidget(DraggableFactory
							.createDraggableModuleImage(new Image("images/"
									+ container[row][col].getType() + ".jpg"),
									dragController));
				}
				// DraggableFactory
				SetWidgetDropController dropController = new SetWidgetDropController(
						simplePanel);
				dragController.registerDropController(dropController);
			}
			yInverter++;
		}
	}

	/**
	 * Clears the map area.
	 */
	public void clearMapGrid() {
		for (int rows = 0; rows < height; rows++) {
			for (int col = 0; col < width; col++) {
				map.setWidget(rows, col, null);
			}
		}
	}

	/**
	 * Gets the map area width
	 * 
	 * @return int Width of the map area
	 */
	public int getMapWidth() {
		return width;
	}

	/**
	 * 
	 * @return int Height of the map area
	 */
	public int getMapHeight() {
		return height;
	}

	/**
	 * The map Grid itself.
	 * 
	 * @return Grid the map Grid
	 */
	public Grid getMap() {
		return map;
	}
	
	/**
	 * Populates the unusable area and copies a list.
	 */
	private void populateAndCopy() {
		// Deep copy of each module to a temporary list.
		tempList = new ModuleList();
		for (Module mod : model.getModuleList()) {
			tempList.add(new Module(mod));
		}

		// Marking unusable area.
		for (int i = 0; i < 10; i++) {
			for (int j = 40; j < 50; j++) {
				map.setWidget(i, j, new Image("images/UNUSABLE.jpg"));
			}
		}
	}
	
	/**
	 * Updates the main list with temp list.
	 */
	private void updateList() {
		model.getModuleList().clear();
		for (Module mod : tempList) {
			model.getModuleList().add(new Module(mod));
		}
		modulePanel.populate();
	}
	
	/**
	 * Builds button listeners.
	 */
	private void buildButtonListeners() {
//		commitButton.addClickHandler(new ClickHandler() {
//			@Override
//			public void onClick(ClickEvent event) {
//				Button ok = new Button("OK");
//				ok.setStyleName("buttonstyle");
//				ok.addClickHandler(new ClickHandler() {
//					@Override
//					public void onClick(final ClickEvent event) {
//						model.getModuleList().clear();
//						updateList();
//						popup.hide();
//					}
//				});
//				Button cancel = new Button("Cancel");
//				cancel.setStyleName("buttonstyle");
//				cancel.addClickHandler(new ClickHandler() {
//					@Override
//					public void onClick(final ClickEvent event) {
//						popup.hide();
//					}
//				});
//				HorizontalPanel panel = new HorizontalPanel();
//				panel.add(ok);
//				panel.add(cancel);
//				popup = new MyPopupPanel(panel, "Commit",
//						"Do You Really Want Commit Changed Modules?\n This Cannot Be Undone!");
//
//			}
//		});
		
		resetButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				Button ok = new Button("OK");
				ok.setStyleName("buttonstyle");
				ok.addClickHandler(new ClickHandler() {
					@Override
					public void onClick(final ClickEvent event) {
						populateAndCopy();
						populate();
						popup.hide();
					}
				});
				Button cancel = new Button("Cancel");
				cancel.setStyleName("buttonstyle");
				cancel.addClickHandler(new ClickHandler() {
					@Override
					public void onClick(final ClickEvent event) {
						popup.hide();
					}
				});
				HorizontalPanel panel = new HorizontalPanel();
				panel.add(ok);
				panel.add(cancel);
				popup = new MyPopupPanel(panel, "Revert",
						"Revert Sandbox And Update Current Modules?\n This Cannot Be Undone!");

			}
		});
	}
	
	/**
	 * Builds the commands for the drag functionality.
	 */
	private void buildDragController() {
		dragController.addDragHandler(new DragHandler() {
			@Override
			public void onDragEnd(final DragEndEvent event) {
				DragContext context = event.getContext();
//				context.selectedWidgets.get(0);
//				Window.alert("Desired X:"+new Double(context.desiredDraggableX).intValue()
//						+ " Mouse X:" + new Double(context.mouseX).intValue());
//				Window.alert("Desired Y:"+ new Double(context.desiredDraggableY).intValue()
//						+ " Mouse Y:" + new Double(context.mouseY).intValue());
			}

			@Override
			public void onDragStart(final DragStartEvent event) {
			}

			@Override
			public void onPreviewDragEnd(final DragEndEvent event)
					throws VetoDragException {
			}

			@Override
			public void onPreviewDragStart(final DragStartEvent event)
					throws VetoDragException {
			}

		});
	}

	/**
	 * Vertical Panel.
	 */
	private VerticalPanel vertPanel;
	/**
	 * Panel for buttons.
	 */
	private HorizontalPanel buttonPanel;
	/**
	 * Panel.
	 */
	private AbsolutePanel absolutePanel;
	/**
	 * Controller
	 */
	private PickupDragController dragController;
	/**
	 * Temp list.
	 */
	private ModuleList tempList;
	/**
	 * Popup.
	 */
	private MyPopupPanel popup;
	/**
	 * Grid.
	 */
	private Grid map;
	/**
	 * Model.
	 */
	private Model model;
	/**
	 * Model.
	 */
	private ModulePanel modulePanel;
	/**
	 * Commit button.
	 */
	private Button commitButton;
	/**
	 * Reset modules button.
	 */
	private Button resetButton;
	/**
	 * CSS string.
	 */
	private String buttonStyle = "buttonstyle";
	/**
	 * Integer height.
	 */
	private final int height;
	/**
	 * Integer width.
	 */
	private final int width;

}
